<template>
  <view class="circle-progress-container">
    <canvas type="2d" id="circleProgress" class="circle-progress"
      :style="{ width: size + 'px', height: size + 'px' }"></canvas>
    <view class="progress-text">
      <text class="current-value">{{ current }}ml</text>
      <text class="separator">/</text>
      <text class="target-value">{{ target }}ml</text>
    </view>
  </view>
</template>

<script>
export default {
  name: 'CircleProgress',
  props: {
    current: {
      type: Number,
      default: 0
    },
    target: {
      type: Number,
      default: 2000
    },
    size: {
      type: Number,
      default: 200
    },
    strokeWidth: {
      type: Number,
      default: 15
    },
    backgroundColor: {
      type: String,
      default: '#E0E0E0'
    },
    progressColor: {
      type: String,
      default: '#4CAF50'
    },
    animationDuration: {
      type: Number,
      default: 1000
    }
  },
  data() {
    return {
      ctx: null,
      animationTimer: null,
      displayValue: 0
    }
  },
  computed: {
    percent() {
      return Math.min(100, Math.round((this.current / this.target) * 100))
    }
  },
  watch: {
    current(newVal, oldVal) {
      this.animateProgress(oldVal, newVal)
    },
    target() {
      this.drawCircle()
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initCanvas()
    })
  },
  beforeUnmount() {
    if (this.animationTimer) {
      clearTimeout(this.animationTimer)
    }
  },
  methods: {
    initCanvas() {
      const query = uni.createSelectorQuery().in(this)
      query.select('#circleProgress')
        .fields({ node: true, size: true })
        .exec((res) => {
          if (res[0] && res[0].node) {
            const canvas = res[0].node
            this.ctx = canvas.getContext('2d')
            
            // 设置canvas尺寸
            const dpr = uni.getSystemInfoSync().pixelRatio
            canvas.width = this.size * dpr
            canvas.height = this.size * dpr
            this.ctx.scale(dpr, dpr)
            
            // 初始绘制
            this.displayValue = this.current
            this.drawCircle()
          } else {
            // 兼容不支持 2d canvas 的平台
            setTimeout(() => {
              const ctx = uni.createCanvasContext('circleProgress', this)
              if (ctx) {
                this.ctx = ctx
                this.displayValue = this.current
                this.drawCircle()
              }
            }, 100)
          }
        })
    },
    
    drawCircle() {
      if (!this.ctx) return
      
      const centerX = this.size / 2
      const centerY = this.size / 2
      const radius = (this.size - this.strokeWidth) / 2
      
      // 清除画布
      this.ctx.clearRect(0, 0, this.size, this.size)
      
      // 绘制背景圆环
      this.ctx.beginPath()
      this.ctx.arc(centerX, centerY, radius, 0, Math.PI * 2)
      this.ctx.strokeStyle = this.backgroundColor
      this.ctx.lineWidth = this.strokeWidth
      this.ctx.stroke()
      
      // 计算进度
      const percent = this.displayValue / this.target
      const endAngle = Math.PI * 2 * Math.min(percent, 1) - Math.PI / 2
      
      // 绘制进度圆环
      this.ctx.beginPath()
      this.ctx.arc(centerX, centerY, radius, -Math.PI / 2, endAngle)
      this.ctx.strokeStyle = this.progressColor
      this.ctx.lineWidth = this.strokeWidth
      this.ctx.lineCap = 'round'
      this.ctx.stroke()
      
      // 如果是旧版canvas API，需要调用draw方法
      if (typeof this.ctx.draw === 'function') {
        this.ctx.draw()
      }
    },
    
    animateProgress(fromValue, toValue) {
      if (this.animationTimer) {
        clearTimeout(this.animationTimer)
      }
      
      const startTime = Date.now()
      const duration = this.animationDuration
      const diff = toValue - fromValue
      
      const animate = () => {
        const elapsed = Date.now() - startTime
        const progress = Math.min(elapsed / duration, 1)
        
        // 使用缓动函数使动画更自然
        const easeProgress = this.easeOutQuad(progress)
        this.displayValue = Math.round(fromValue + diff * easeProgress)
        
        this.drawCircle()
        
        if (progress < 1) {
          this.animationTimer = setTimeout(animate, 16)
        } else {
          this.displayValue = toValue
          this.drawCircle()
        }
      }
      
      animate()
    },
    
    easeOutQuad(t) {
      return t * (2 - t)
    }
  }
}
</script>

<style lang="scss">
.circle-progress-container {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  
  .circle-progress {
    position: relative;
  }
  
  .progress-text {
    position: absolute;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    
    .current-value {
      font-size: 24px;
      font-weight: bold;
      color: #333;
    }
    
    .separator {
      font-size: 16px;
      color: #666;
      margin: 2px 0;
    }
    
    .target-value {
      font-size: 16px;
      color: #666;
    }
  }
}
</style>